package logic.nodes.nodeSettings.upgrades;

import java.util.HashMap;

import logic.nodes.nodeSettings.AbstractSettings;
import logic.nodes.nodeSettings.Settings;
import main.listeners.ListenerContainer;

public class UpgradableSettings extends AbstractSettings<UpgradableOption> {
	
	protected int costs;
	protected String modelPath, filePath;
	protected ListenerContainer upgradeListeners;
	
	public UpgradableSettings(int costs, String modelPath, String filePath) {
		super();
		this.costs = costs;
		this.modelPath = modelPath;
		this.filePath = filePath;
		
		initUpgradeListeners();
	}
	
	public UpgradableSettings(UpgradableSettings settings) {
		super(settings);
		
		initUpgradeListeners();
	}
	
	protected void initUpgradeListeners() {
		upgradeListeners = new ListenerContainer(UpgradeListener.class);
	}
	
	public void addUpgradeListener(UpgradeListener l) { upgradeListeners.addListener(l); }
	
	public void removeUpgradeListener(UpgradeListener l) { upgradeListeners.removeListener(l); }
	
	public String getValueOfLevel(String key, int level) {
		UpgradableOption option = getOption(key);
		return option.getValueOfLevel(level);
	}
	
	public synchronized void addOption(String infoType, HashMap<String, UpgradeValue> values) {
		UpgradableOption option = getOption(infoType);
		if(option == null) {
			option = new UpgradableOption(infoType, values);
			optionMap.put(infoType, option);
		}
	}
	
	public String getMaxValueOf(String key) {
		int maxLevel = getMaxUpgradeLevelOf(key);
		return getValueOfLevel(key, maxLevel);
	}
	
	public int getLevelOf(String key) {
		UpgradableOption option = getOption(key);
		return option.getLevel();
	}
	
	public HashMap<String, UpgradeValue> getValueMapOf(String key) {
		return getOption(key).getValues();
	}
	
	public int getMaxUpgradeLevelOf(String key) {
		UpgradableOption option = getOption(key);
		return option.getMaxLevel();
	}
	
	public void upgrade(String key) {
		upgrade(key, false);
	}
	
	public void upgrade(String key, boolean silently) {
		UpgradableOption option = getOption(key);
		option.upgrade();
		
		if(!silently) {
			UpgradeEvent event = new UpgradeEvent(key, option.getValue());
			upgradeListeners.callMethod(UpgradeListener.UPGRADED, event);
		}
	}
	
	public boolean isFullyUpgraded(String key) {
		UpgradableOption option = getOption(key);
		return option.getLevel() == option.getMaxLevel();
	}
	
	public int getCosts() { return costs; }
	
	public String getModelPath() { return "data/models/" + modelPath; }
	
	public String getCopyModelPath() { return modelPath; }
	
	public String getFilePath() { return filePath; }
	
	public int getUpgradeCost(String key) {
		UpgradableOption option = getOption(key);
		return option.getUpgradeCosts();
	}
	
	public void resetLevel() {
		for(UpgradableOption option : optionMap.values()) {
			option.reset();
		}
	}
	
	public Settings getMaxValues() {
		Settings settings = new Settings();
		
		for(UpgradableOption option : optionMap.values()) {
			settings.addOption(option.getKey(), option.getValueOfLevel(option.getMaxLevel()));
		}
		return settings;
	}
	
	@Override
	public synchronized void copySettings(AbstractSettings<UpgradableOption> settings, boolean reset) {
		super.copySettings(settings, reset);
		UpgradableSettings upgradeSettings = (UpgradableSettings)settings;
		costs = upgradeSettings.getCosts();
		modelPath = upgradeSettings.getCopyModelPath();
		filePath = upgradeSettings.getFilePath();
	}
}